use super::*;

#[derive(Clone, Copy)]
pub struct Table<'a> {
	// int16	format version number
	pub format: i16,
	// int16	number of device records
	pub num_records: i16,
	// int32	size of a device record, long aligned
	pub size_record: i32,
	// DeviceRecord	records[number of device records]
	pub data: &'a [u8],
	pub num_glyphs: u16,
}
impl<'a> Table<'a> {
	pub fn parse(num_glyphs: u16, data: &'a [u8]) -> Option<Self> {
		let mut s = Stream::new(data);
		Some(Self {
			format: s.read()?,
			num_records: s.read()?,
			size_record: {
				let mut size = s.read()?;
				if size >= 0x0FFF0000 {
					size &= 0xFFFF;
				}
				size
			},
			data: s.tail()?,
			num_glyphs,
		})
	}
	pub fn get(&self, index: i16) -> Option<DeviceRecord<'a>> {
		let start = (index as i32 * self.size_record) as usize;
		let end = start.checked_add(self.num_glyphs.into())?;
		self.data.get(start..end).and_then(DeviceRecord::parse)
	}
}
impl<'a> core::fmt::Debug for Table<'a> {
	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
		f.debug_struct("Table")
			.field("format", &self.format)
			.field("num_records", &self.num_records)
			.field("size_record", &self.size_record)
			.field(
				"records",
				&(0..self.num_records).into_iter().map(|v| self.get(v)).collect::<Vec<_>>(),
			)
			// .field("data", &self.data)
			.finish()
	}
}

#[derive(Clone, Copy)]
pub struct DeviceRecord<'a> {
	pub ppem: u8,       //pixel size for following widths
	pub max_width: u8,  // maximum width
	pub data: &'a [u8], // widths[number of glyphs]
}
impl<'a> DeviceRecord<'a> {
	pub fn parse(data: &'a [u8]) -> Option<Self> {
		let mut s = Stream::new(data);
		Some(DeviceRecord {
			ppem: s.read()?,
			max_width: s.read()?,
			data: s.tail()?,
		})
	}
	pub fn get(&self, index: u16) -> Option<u8> {
		self.data.get(index as usize).copied()
	}
}
impl<'a> core::fmt::Debug for DeviceRecord<'a> {
	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
		f.debug_struct("DeviceRecord")
			.field("ppem", &self.ppem)
			.field("max_width", &self.max_width)
			.field("data", &self.data)
			.finish()
	}
}
